import { Math, Cartographic, Cartesian3, Matrix4 } from "cesium";
import { setDefaultValue, isUndefined } from "./common";

export const lngLatValid = (lng, lat) => {
	if (isUndefined(lng) || isUndefined(lat)) {
		throw new Error("lng/lat is undefined!");
	}
	return true;
};

/**
 * @name 经纬度转化为笛卡尔
 * @param {Object} degree 经纬度对象
 * @param {Number} degree.lng 经度
 * @param {Number} degree.lat 纬度
 * @returns
 */
export const lngLatToCartesian3 = ({ lng, lat, height }) => {
	return Cartesian3.fromDegrees(setDefaultValue(lng, 0), setDefaultValue(lat, 0), setDefaultValue(height, 0));
};

/**
 * @name 经纬度数组转化为笛卡尔数组
 * @param {Object} degree 经纬度对象
 * @param {Number} degree.lng 经度
 * @param {Number} degree.lat 纬度
 * @returns
 */
export const lngLatsToCartesian3s = (arr = []) => {
	return arr.map(lngLatToCartesian3);
};

/**
 * @name 经纬度对象转为经纬度数组
 * @param {Object} degree 经纬度对象
 * @param {Number} degree.lng 经度
 * @param {Number} degree.lat 纬度
 * @returns
 */
export const lngLatToDegreeArray = ({ lng, lat }) => {
	lngLatValid(lng, lat);
	return [lng, lat];
};

/**
 * @name 经纬度对象数组转为经纬度数组
 * @param {Array} degreesArray 经纬度数组
 * @returns
 */
export const lngLatsToDegreesArray = (lngLatsArray = []) => {
	if (!Array.isArray(lngLatsArray)) {
		return [];
	}
	return lngLatsArray.reduce((v, c) => {
		return [...v, ...lngLatToDegreeArray(c)];
	}, []);
};

/**
 * @name 经纬度对象数组转为笛卡尔数组
 * @param {Array} degreesArray //经纬度数组
 * @returns
 */
export const lngLatsToCartesian3Array = (lngLatsArray = []) => {
	if (!Array.isArray(lngLatsArray) || !lngLatsArray.length) {
		return [];
	}
	return Cartesian3.fromDegreesArray(lngLatsToDegreesArray(lngLatsArray));
};

/**
 * @name 经纬度转大地坐标
 * @param {LngLat} param0
 * @returns
 */
export const lngLatToCartographic = ({ lng, lat, height }) => {
	lngLatValid(lng, lat);
	return Cartographic.fromDegrees(lng, lat, height);
};

/**
 * @name 大地坐标转经纬度
 * @param {Cartographic} param0
 * @returns
 */
export const cartoGraphicToLngLat = ({ longitude: lng, latitude: lat, height }) => {
	lngLatValid(lng, lat);
	return {
		lng: Math.toDegrees(lng),
		lat: Math.toDegrees(lat),
		height,
	};
};

/**
 * @name 笛卡尔坐标转经纬度
 * @param {Cartesian3} cartesian 笛卡尔坐标
 * @returns
 */
export const cartesian3ToLngLat = (cartesian) => {
	return cartoGraphicToLngLat(Cartographic.fromCartesian(cartesian));
};
